package com.robertux.leaderboard.util.gestoresModelos;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;

import org.apache.log4j.Logger;

import com.robertux.leaderboard.beans.EstadoEntidad;
import com.robertux.leaderboard.beans.entities.DetalleGrupoProducto;
import com.robertux.leaderboard.beans.entities.GrupoProducto;
import com.robertux.leaderboard.beans.entities.external.Producto;

public class GestorGruposProductos {
	private GestorEntidades<GrupoProducto> gGPrd;
	private Logger logger;
	
	public GestorGruposProductos() {
		this(new GestorEntidades<GrupoProducto>());
	}
	
	public GestorGruposProductos(GestorEntidades<GrupoProducto> gestor) {
		this.gGPrd = gestor;
		this.logger = Logger.getLogger(this.getClass());
	}
	
	public List<GrupoProducto> getGruposProductos() {
		TypedQuery<GrupoProducto> qry = this.gGPrd.getEntityManager().createQuery("SELECT gp FROM GrupoProducto gp WHERE gp.estado <> :estado", GrupoProducto.class);
		qry.setParameter("estado", EstadoEntidad.ELIMINADO.getCodigo());
		try {
			return qry.getResultList();
		} catch (Exception e) {
			this.logger.error("Error tratando de consultar los grupos de prodcutos: " + e.getMessage(), e);
			return new ArrayList<GrupoProducto>();
		}
	}
	
	public List<GrupoProducto> getGruposProductos(int pagina, int filasPorPagina, String filtro) {
		TypedQuery<GrupoProducto> qry = this.gGPrd.getEntityManager().createQuery("SELECT gp FROM GrupoProducto gp WHERE gp.estado <> :estado"
				+ (filtro != null && filtro.trim().length() > 0? " AND (UPPER(gp.nombre) LIKE UPPER(:filtro))": ""), GrupoProducto.class);
		qry.setParameter("estado", EstadoEntidad.ELIMINADO.getCodigo());
		
		if(filtro != null && filtro.trim().length() > 0) {
			qry.setParameter("filtro", "%" + filtro + "%");
		}
		qry.setFirstResult((pagina-1) * filasPorPagina);
		qry.setMaxResults(filasPorPagina);
		
		try {
			return qry.getResultList();
		} catch (Exception e) {
			this.logger.error("Error tratando de consultar los grupos de prodcutos: " + e.getMessage(), e);
			return new ArrayList<GrupoProducto>();
		}
	}
	
	public long getTotalGruposProductos(String filtro) {
		TypedQuery<Long> qry = this.gGPrd.getEntityManager().createQuery("SELECT count(gp.id) FROM GrupoProducto gp WHERE gp.estado <> :estado"
				+ (filtro != null && filtro.trim().length() > 0? " AND (UPPER(gp.nombre) LIKE UPPER(:filtro))": ""), Long.class);
		qry.setParameter("estado", EstadoEntidad.ELIMINADO.getCodigo());
		
		if(filtro != null && filtro.trim().length() > 0) {
			qry.setParameter("filtro", "%" + filtro + "%");
		}
		
		try {
			return qry.getSingleResult();
		} catch (NoResultException nrE) {
			return 0;
		} catch (Exception e) {
			this.logger.error("Error tratando de consultar el total de evaluaciones: " + e.getMessage(), e);
			return 0;
		}
	}
	
	public GrupoProducto getGrupoProducto(int gpId) {
		return this.gGPrd.getEntidad("GrupoProducto", GrupoProducto.class, gpId);
	}
	
	public GrupoProducto getGrupoProducto(String gpNombre) {
		TypedQuery<GrupoProducto> qry = this.gGPrd.getEntityManager().createQuery("SELECT gp FROM GrupoProducto gp WHERE gp.nombre = :nombre", GrupoProducto.class);
		qry.setParameter("nombre", gpNombre);
		try {
			return qry.getSingleResult();
		} catch (NoResultException nrE) {
			return null;
		} catch (Exception e) {
			this.logger.error("Error tratando de consultar los grupos de prodcutos: " + e.getMessage(), e);
			return null;
		}
	}
	
	public boolean agregarGrupoProducto(GrupoProducto gPrd) {
		try {
			this.gGPrd.persistir(gPrd);
			return true;
		} catch (Exception e) {
			this.logger.error("Error tratando de guardar el grupo de producto: " + e.getMessage(), e);
			return false;
		}
	}
	
	public boolean actualizarGrupoProducto(GrupoProducto gp) {
		try {
			this.gGPrd.actualizar(gp);
			return true;
		} catch (Exception e) {
			this.logger.error("Error tratando de actualizar el grupo de productos: " + e.getMessage(), e);
			return false;
		}
	}
	
	public boolean eliminarGrupoProducto(GrupoProducto gp) {
		try {
			gp.setEstado(EstadoEntidad.ELIMINADO.getCodigo());
			this.gGPrd.actualizar(gp);
			return true;
		} catch (Exception e) {
			this.logger.error("Error tratando de eliminar el grupo de productos: " + e.getMessage(), e);
			return false;
		}
	}
	
	public boolean eliminarDetalleProducto(DetalleGrupoProducto detGPrd) {
		try {
			this.gGPrd.getEntityManager().getTransaction().begin();
			this.gGPrd.getEntityManager().remove(this.gGPrd.getEntityManager().merge(detGPrd));
			this.gGPrd.getEntityManager().getTransaction().commit();
			return true;
		} catch (Exception e) {
			this.logger.error("Error tratando de eliminar el detalle de grupo de producto: " + e.getMessage(), e);
			return false;
		}
	}
	
	public GestorEntidades<GrupoProducto> getgGPrd() {
		return gGPrd;
	}
	public Logger getLogger() {
		return logger;
	}
	
	public Collection<Producto> getProductos() {
		return new GestorEntidadesFarmacia().getProductos();
	}
	
	public Map<String, Producto> getProductosMap() {
		return new GestorEntidadesFarmacia().getProductosMap();
	}
	
	public Collection<Producto> getProductos(int pagina, int filasPorPagina, String filtro) {
		return new GestorEntidadesFarmacia().getProductos(pagina, filasPorPagina, filtro);
	}
	
}
